#property copyright   "Copyright 2012,"
#property link "mxhe2001@hotmail.com"

#define LONG          0
#define SHORT         1
#define ALL           2
#define RETRYCOUNT    10   
#define RETRYDELAY    500

extern string StarsIndicatorName = "3_level_zz"; 
extern double Period1=5; 
extern double Period2=13; 
extern double Period3=34; 
extern string Dev_Step_1="1,3";
extern string Dev_Step_2="8,5";
extern string Dev_Step_3="21,12";
extern bool   Star1Enable = true;
extern bool   Star2Enable = true;
extern bool   Star3Enable = true;
extern string NanoSRIndicatorName = "Nano S_R";

extern bool   NanoSRConfirm = true;

extern string Money_Management_Setting ="------Money Management Setting------";
//extern double MaxDrawdownPercent = 20;
extern double FixedOrderSize = 0.1; 
extern double MartingleFactor  = 2;
extern bool   NoOpenAtDD = true;
extern double DDPercentOfBalance = 10;
extern bool   CloseAtProfitInPercentOfBalance = true;
extern double ProfitInPercentOfBalance = 20;
extern bool   CloseAtProfitInDollar = true;
extern double ProfitInDollar = 100;
extern double HedgingGap = 30;
extern double LevelDistance = 50;

extern string Other_Setting ="------Other Setting------";
extern string start.time = "00:00"; 
extern string end.time = "23:59";
extern int    MagicNumber=-1;
extern int    Slippage = 3;
extern int    Shift = 0;

datetime lastBuyTime, lastSellTime;
int digitFactor = 1;
int lastOrderHisTotal;
int orders.total, orders.BUY, orders.SELL, orders.BUYLIMIT, orders.BUYSTOP, orders.SELLLIMIT, orders.SELLSTOP;
bool NoTrades = false;
double nextOrderSize;
double highestOpenPrice, lowestOpenPrice;
int lotDigits;
double initBalance;

int init()
{    
    if(Bid<10 && Digits==5) { digitFactor=10;}
    if(Bid<10 && Digits==4) { digitFactor= 1;}

    if(Bid>10 && Digits==3) { digitFactor=10;}
    if(Bid>10 && Digits==2) { digitFactor= 1;}   
    
    HedgingGap *= digitFactor; 
    LevelDistance *= digitFactor; 
    
    if (MagicNumber < 0)
    {
        sub_magicnumber();
    }
    
    lastOrderHisTotal = OrdersHistoryTotal();
    
    nextOrderSize = FixedOrderSize;
    
    NoTrades = false;
    
    initBalance = AccountBalance();
    
    lotDigits = MathLog(MarketInfo(Symbol(), MODE_LOTSTEP))/MathLog(0.1); 
}

int start()
{
    double lowStar1 = iCustom(NULL, 0, StarsIndicatorName, Period1, Period2, Period3, Dev_Step_1, Dev_Step_2, Dev_Step_3, 0, Shift);
    double hightStar1 = iCustom(NULL, 0, StarsIndicatorName, Period1, Period2, Period3, Dev_Step_1, Dev_Step_2, Dev_Step_3, 1, Shift);
    double lowStar2 = iCustom(NULL, 0, StarsIndicatorName, Period1, Period2, Period3, Dev_Step_1, Dev_Step_2, Dev_Step_3, 2, Shift);
    double hightStar2 = iCustom(NULL, 0, StarsIndicatorName, Period1, Period2, Period3, Dev_Step_1, Dev_Step_2, Dev_Step_3, 3, Shift);
    double lowStar3 = iCustom(NULL, 0, StarsIndicatorName, Period1, Period2, Period3, Dev_Step_1, Dev_Step_2, Dev_Step_3, 4, Shift);
    double hightStar3 = iCustom(NULL, 0, StarsIndicatorName, Period1, Period2, Period3, Dev_Step_1, Dev_Step_2, Dev_Step_3, 5, Shift);
   
    double Resist1 = iCustom(NULL, 0, NanoSRIndicatorName, 0, Shift);      
    double Support1 = iCustom(NULL, 0, NanoSRIndicatorName, 1, Shift);
    double Resist2 = iCustom(NULL, 0, NanoSRIndicatorName, 2, Shift);      
    double Support2 = iCustom(NULL, 0, NanoSRIndicatorName, 3, Shift);    
    double Resist3 = iCustom(NULL, 0, NanoSRIndicatorName, 4, Shift);      
    double Support3 = iCustom(NULL, 0, NanoSRIndicatorName, 5, Shift); 
    
    bool isTradeTime = isTradingTime();
    
    if (isTradeTime && !NoTrades && 
         ( (Star3Enable && hightStar3 > 0 && hightStar3 != EMPTY_VALUE && (!NanoSRConfirm || hightStar3 == Resist3)) || 
           (Star2Enable && hightStar2 > 0 && hightStar3 == EMPTY_VALUE && hightStar2 != EMPTY_VALUE && (!NanoSRConfirm || hightStar2 == Resist1 || hightStar2 == Resist2 || hightStar2 == Resist3)) ||
           (Star1Enable && hightStar1 > 0 && hightStar3 == EMPTY_VALUE && hightStar2 == EMPTY_VALUE && hightStar1 != EMPTY_VALUE && (!NanoSRConfirm || hightStar1 == Resist1 || hightStar1 == Resist2 || hightStar1 == Resist3))) && 
        (Bid > highestOpenPrice + LevelDistance*Point || highestOpenPrice == 0) && Time[0] > lastSellTime)
    {
         int sellTicket = DoOpenOrder(Symbol(), SHORT, nextOrderSize, 0, 0, Red, "");
         if (sellTicket > 0)
         {
             if (OrderSelect(sellTicket, SELECT_BY_TICKET))
             {
                 lastSellTime = Time[0];
                 double hedgeOrderOpenPrice = OrderOpenPrice() + HedgingGap*Point;
                 if (DoPendingLot(Symbol(), LONG, OP_BUYSTOP, hedgeOrderOpenPrice, nextOrderSize, 0, 0, "") > 0)
                 {
                     if (highestOpenPrice < hedgeOrderOpenPrice)
                     {
                         highestOpenPrice = hedgeOrderOpenPrice;
                     }
                 }
                 
                 if (lowestOpenPrice > OrderOpenPrice()  || lowestOpenPrice == 0)
                 {
                     lowestOpenPrice = OrderOpenPrice();
                 }
             }
             
             nextOrderSize = NormalizeDouble(nextOrderSize*MartingleFactor, lotDigits);
         }
    }
    
     if (isTradeTime && !NoTrades && 
         ( (Star3Enable && lowStar3 > 0 && lowStar3 != EMPTY_VALUE && (!NanoSRConfirm || lowStar3 == Support3)) || 
           (Star2Enable && lowStar2 > 0 && lowStar3 == EMPTY_VALUE && lowStar2 != EMPTY_VALUE && (!NanoSRConfirm || lowStar2 == Support1 || lowStar2 == Support2 || lowStar2 == Support3)) ||
           (Star1Enable && lowStar1 > 0 && lowStar3 == EMPTY_VALUE && lowStar2 == EMPTY_VALUE && lowStar1 != EMPTY_VALUE && (!NanoSRConfirm || lowStar1 == Support1 || lowStar1 == Support2 || lowStar1 == Support3))) && 
    
        (Ask < lowestOpenPrice - LevelDistance*Point || lowestOpenPrice == 0)  && Time[0] > lastBuyTime)
    {
         int buyTicket = DoOpenOrder(Symbol(), LONG, nextOrderSize, 0, 0, Blue, "");
         if (buyTicket > 0)
         {
             if (OrderSelect(buyTicket, SELECT_BY_TICKET))
             {
                 lastBuyTime = Time[0];
                 hedgeOrderOpenPrice = OrderOpenPrice() - HedgingGap*Point;
                 if (DoPendingLot(Symbol(), SHORT, OP_SELLSTOP, hedgeOrderOpenPrice, nextOrderSize, 0, 0, "") > 0)
                 {
                     if (lowestOpenPrice > hedgeOrderOpenPrice  || lowestOpenPrice == 0)
                     {
                         lowestOpenPrice = hedgeOrderOpenPrice;
                     }
                 }
                 
                 if (highestOpenPrice < OrderOpenPrice())
                 {
                     highestOpenPrice = OrderOpenPrice();
                 }
             }
             
             nextOrderSize = NormalizeDouble(nextOrderSize*MartingleFactor, lotDigits);           
         }
    }
    
    if (CloseAtProfitInPercentOfBalance)
    {
        if (getLiveProfit() >=  ProfitInPercentOfBalance*AccountBalance()/100)
        {
            ExitAll(LONG);
            ExitAll(SHORT);
            DeletePendings(LONG);
            DeletePendings(SHORT);
            nextOrderSize = FixedOrderSize;
            highestOpenPrice = 0;
            lowestOpenPrice = 0;
            //NoTrades = false;
        }
    }
    
    double getLiveProfit;
    getLiveProfit = getLiveProfit();
    if (NoOpenAtDD)
    {
        
        if (AccountEquity() <= (100-DDPercentOfBalance)*initBalance/100)
        {
            NoTrades = true;
        }
    }
    
    Comment("NoTrades:",NoTrades, " AccountBalance:",initBalance, " getLiveProfit():",getLiveProfit, " -DDPercentOfBalance*initBalance/100:",-DDPercentOfBalance*initBalance/100);
    
    if (CloseAtProfitInDollar)
    {
        if (getLiveProfit() >= ProfitInDollar)
        {
            ExitAll(LONG);
            ExitAll(SHORT);
            DeletePendings(LONG);
            DeletePendings(SHORT);
            nextOrderSize = FixedOrderSize;
            highestOpenPrice = 0;
            lowestOpenPrice = 0;
            //NoTrades = false;
        }
    }
}

bool isTradingTime()
{
   bool isTT = false;

   datetime tm0 = TimeCurrent();
   datetime tm1, tm2;

   tm1 = StrToTime(TimeToStr(tm0, TIME_DATE) + " " + start.time);
   tm2 = StrToTime(TimeToStr(tm0, TIME_DATE) + " " + end.time);

   if (tm1 <= tm2) 
     isTT = tm1 <= tm0 && tm0 <= tm2;

   return (isTT);
}

bool DeletePendings(int direction) {
   
   bool pendings;
   int i;
   
   CountOrders(); 
   if( (orders.SELLLIMIT != 0 || orders.SELLSTOP != 0) && direction == SHORT) 
   {
      while(orders.SELLLIMIT != 0 || orders.SELLSTOP != 0) 
      {
         for(i = OrdersTotal() - 1; i >= 0; i--) 
         {
            if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
            
            pendings = OrderType() == OP_SELLLIMIT || OrderType() == OP_SELLSTOP;            
            if( OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol() && pendings ) 
            {              
               OrderDelete( OrderTicket() );
            }
         }          
         CountOrders();                 
      }
      
      return( true );
   }
   
   if ((orders.BUYLIMIT != 0 || orders.BUYSTOP != 0) && direction == LONG) 
   {      
      while((orders.BUYLIMIT != 0 || orders.BUYSTOP != 0)) 
      {
         for(i = OrdersTotal() - 1; i >= 0; i--) 
         {         
            if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
  
            pendings = OrderType() == OP_BUYLIMIT || OrderType() == OP_BUYSTOP;
            if( OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol() && pendings) 
            {              
               OrderDelete(OrderTicket());
            }
         }          
         CountOrders();       
      }
      
      return( true );
   }   
}

//close all open positions with the specified LONG or SHORT direction
void ExitAll(int direction) {

   int i;
   
   CountOrders(); 
   if( orders.SELL != 0 && direction == SHORT) 
   {      
      while( orders.SELL != 0 ) 
      {
         for(i = OrdersTotal() - 1; i >= 0; i--) 
         {
            if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;       
            if( OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol() ) 
            {              
                if (OrderType() == OP_SELL) { Exit( OrderTicket(), Symbol(), OP_SELL, OrderLots(), Red); }
            }
         }          
         CountOrders();                 
      }      
      return( true );
   }
   
   if( orders.BUY != 0 && direction == LONG) 
   {  
      while( orders.BUY != 0 ) 
      {
         for(i = OrdersTotal() - 1; i >= 0; i--) 
         {         
            if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
            if( OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol()) {              
                if (OrderType() == OP_BUY) { Exit(OrderTicket(), Symbol(), OP_BUY, OrderLots(), Blue); }
            }
         } 
         
         CountOrders();       
      }      
      return( true );
   }   
}

//close an order with specifed ticket, if failed try again with RETRYCOUNT times
bool Exit(int ticket, string symbolName, int dir, double volume, color clr)  {
    int i, j, cmd;
    double prc, sl, tp, lots;
    string cmt;

    bool closed;

    Print("Exit("+dir+","+DoubleToStr(volume,3)+")");

    for (i=0; i<RETRYCOUNT; i++) {
        for (j=0; (j<50) && IsTradeContextBusy(); j++)
            Sleep(100);
        RefreshRates();

        if (dir == OP_BUY) {
            prc = MarketInfo(symbolName, MODE_BID);
        }
        if (dir == OP_SELL) {
            prc = MarketInfo(symbolName, MODE_ASK);
       }
        Print("Exit: prc="+DoubleToStr(prc,MarketInfo(symbolName, MODE_DIGITS)));

        closed = OrderClose(ticket,volume,prc,Slippage,clr);
        if (closed) {
            Print("Trade closed");

            return (true);
        }

        Print("Exit: error \'"+ErrorDescription(GetLastError())+"\' when exiting with "+DoubleToStr(volume,3)+" @"+DoubleToStr(prc,MarketInfo(symbolName, MODE_DIGITS)));
        Sleep(RETRYDELAY);
    }

    Print("Exit: can\'t enter after "+RETRYCOUNT+" retries");
    return (false);
}

//Count Orders and calculate the group's average entry point & spread
int CountOrders() 
{
   orders.BUY = 0;
   orders.SELL = 0;
   orders.BUYLIMIT = 0;
   orders.BUYSTOP = 0;
   orders.SELLLIMIT = 0;
   orders.SELLSTOP = 0;
   
   for( int i = OrdersTotal() - 1; i >= 0; i--) 
   {   
      if (!OrderSelect( i, SELECT_BY_POS)) continue;
      
      if( OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber ) 
      {                       
         if( OrderType() == OP_BUY ) 
         { 
             orders.BUY++; 
         }
         if( OrderType() == OP_SELL ) 
         { 
             orders.SELL++; 
         }
         if( OrderType() == OP_BUYLIMIT ) 
         { 
             orders.BUYLIMIT++; 
         }
         if( OrderType() == OP_BUYSTOP ) 
         { 
             orders.BUYSTOP++; 
         }
         if( OrderType() == OP_SELLLIMIT ) 
         { 
             orders.SELLLIMIT++; 
         }
         if( OrderType() == OP_SELLSTOP ) 
         { 
             orders.SELLSTOP++; 
         }
      }
   }
   
   orders.total = orders.BUY + orders.SELL;
   
   return(orders.total);

}

double getLiveProfit()
{
    double profit = 0;
    for (int i = OrdersTotal() - 1; i >= 0; i--)
    {
        if (OrderSelect(i, SELECT_BY_POS))
        {
            if (OrderMagicNumber() == MagicNumber)
            {
                profit += OrderProfit();
            }
        }
    }
    
    return (profit);
}

//  Magic Number - calculated from a sum of account number and ASCII-codes from currency pair                                                                           
int sub_magicnumber()
{
     string local_currpair = Symbol();
     int local_length = StringLen (local_currpair);
     int local_asciisum = 0;
     int local_counter;

     for (local_counter = 0; local_counter < local_length -1; local_counter++)
        local_asciisum += StringGetChar (local_currpair, local_counter);
     MagicNumber = AccountNumber() + local_asciisum;   
}

//open an order, if failed try again with RETRYCOUNT times
int DoOpenOrder(string symbolName, int dir, double volume, int stop, int take, color clr, string comment = "")  {

   double sl, tp, entryPrice;

   int ticket = 0;   

   double lots = volume;
   string info;
   
   double dAsk = MarketInfo(symbolName, MODE_ASK);
   double dBid = MarketInfo(symbolName, MODE_BID);
   double dPoint = MarketInfo(symbolName, MODE_POINT);
   double dDigits = MarketInfo(symbolName, MODE_DIGITS);
   
   for (int i=0; i<RETRYCOUNT; i++) {
     for (int j=0; (j<50) && IsTradeContextBusy(); j++)
         Sleep(100);
      RefreshRates();   

      switch(dir)  {
         case LONG:               
               entryPrice = NormalizeDouble(dAsk, dDigits);
               
               if (stop != 0) { sl = entryPrice-(stop*dPoint); }
                else { sl = 0; }
                if (take != 0) { tp = entryPrice +(take*dPoint); }
                else { tp = 0; }
                
                
                info = "Type: " + dir + ", \nentryPrice: " + DoubleToStr(entryPrice, dDigits) 
                   + ", \nLots " + DoubleToStr(lots, 2) + " , \nStop: " + DoubleToStr(sl, dDigits)  
                   + ", \nTP: " + DoubleToStr(tp, dDigits);
                Print(info);
                Comment(info);                
               
                ticket = OrderSend(symbolName, OP_BUY, lots, entryPrice, Slippage, sl, tp, comment, MagicNumber, 0, clr);
                if (ticket < 0)  
                {
                    ticket = OrderSend(symbolName, OP_BUY, lots, entryPrice, Slippage, 0, 0, comment, MagicNumber, 0, clr);                    
                }
                if (ticket > 0)  
                {
                     if(OrderSelect(ticket, SELECT_BY_TICKET))
                     {
                         modifyOrderByPrice(ticket, OrderOpenPrice(), sl, tp);
                     }
                }
                
                break;

         case SHORT:
              entryPrice = NormalizeDouble(dBid, dDigits);
              if (stop != 0) { sl = entryPrice+(stop*dPoint); }
                else { sl = 0; }
                if (take != 0) { tp = entryPrice-(take*dPoint); }
                else { tp = 0; }
                
                info = "Type: " + dir + ", \nentryPrice: " + DoubleToStr(entryPrice, dDigits)
                   + ", \nLots " + DoubleToStr(lots, 2) + " , \nStop: " + DoubleToStr(sl, dDigits)  
                   + ", \nTP: " + DoubleToStr(tp, dDigits);
              Print(info);
              Comment(info);
          
                ticket = OrderSend(symbolName, OP_SELL, lots, entryPrice, Slippage, sl, tp, comment, MagicNumber, 0, clr);     
                if (ticket < 0)  
                {
                    ticket = OrderSend(symbolName, OP_SELL, lots, entryPrice, Slippage, 0, 0, comment, MagicNumber, 0, clr);                    
                    
                }   
                if (ticket > 0)  
                {
                   if(OrderSelect(ticket, SELECT_BY_TICKET))
                   {
                       modifyOrderByPrice(ticket, OrderOpenPrice(), sl, tp);
                   }
                }                      
                break;
      }
           
      if( ticket > 0 ) { return( ticket ); }
      else {
         Print("DoOpenOrder: error \'"+ErrorDescription(GetLastError())+"\' when opening entry order");
         Sleep(RETRYDELAY);      
      }
      
   }
      
   return( false );
}

//modify an order with specified ticket, if failed try again with RETRYCOUNT times
bool modifyOrderByPrice(int ticket, double price, double stopLoss, double takeProfit)  
{
   bool retVal = true;     
   
   if(!OrderSelect(ticket, SELECT_BY_TICKET)) return (false);
   
   for (int i=0; i<RETRYCOUNT; i++) 
   {
     for (int j=0; (j<50) && IsTradeContextBusy(); j++)
        Sleep(100);
      RefreshRates();                        

       if (MathAbs(OrderStopLoss() - stopLoss) > Point || MathAbs(OrderTakeProfit() - takeProfit) > Point)
       {              
           retVal = OrderModify(ticket, price, stopLoss, takeProfit, 0);
       }
         
      if(retVal) { return( true ); } 
      else {
         Print("DoModifyOrder: error \'"+ErrorDescription(GetLastError())+"\' when modifying order SL:", stopLoss, " TP:", takeProfit, " OrderOpenPrice:",OrderOpenPrice(), " OrderStopLoss:",OrderStopLoss());
         Sleep(RETRYDELAY);      
      }  
   }      
   return( false );
}

//open a pending order, if failed try again with RETRYCOUNT times
int DoPendingLot(string symbolName, int dir, int pendingType, double entryPrice, double volume, int stop, int take, string comment)  {
   
   int retVal = -1;   
   double sl, tp;
   double _Point = MarketInfo(symbolName, MODE_POINT); 
   double _Digits = MarketInfo(symbolName, MODE_DIGITS);
   string info;
   
   for (int i=0; i<RETRYCOUNT; i++) {
     for (int j=0; (j<50) && IsTradeContextBusy(); j++)
         Sleep(100);
      RefreshRates();   

      switch(dir)  {
         case LONG:                               
                if (stop != 0) { sl = entryPrice-(stop*_Point); }
                else { sl = 0; }
                if (take != 0) { tp = entryPrice +(take*_Point); }
                else { tp = 0; }
                                              
                info = "Type: " + pendingType + ", \nentryPrice: " + DoubleToStr(entryPrice, _Digits) + ", \nAsk " + DoubleToStr(MarketInfo(symbolName, MODE_ASK),_Digits)
                   + ", \nLots " + DoubleToStr(volume, 2) + " , \nStop: " + DoubleToStr(sl, _Digits)  
                   + ", \nTP: " + DoubleToStr(tp, _Digits);
                Print(info);
                Comment(info);                
                               
                retVal = OrderSend(symbolName, pendingType, volume, entryPrice, Slippage, sl, tp, comment, MagicNumber, 0, Olive);
                if (retVal < 0)  
                {
                    retVal = OrderSend(symbolName, pendingType, volume, entryPrice, Slippage, 0, 0, comment, MagicNumber, 0, Blue);                    
                    modifyOrderByPrice(retVal, entryPrice, sl, tp);
                }
                break;

         case SHORT:               
                if (stop != 0) { sl = entryPrice+(stop*_Point); }
                else { sl = 0; }
                if (take != 0) { tp = entryPrice-(take*_Point); }
                else { tp = 0; }
                
                info = "Type: " + pendingType + ", \nentryPrice: " + DoubleToStr(entryPrice, _Digits) + ", \nBid " + DoubleToStr(MarketInfo(symbolName, MODE_BID),_Digits)
                   + ", \nLots " + DoubleToStr(volume, 2) + " , \nStop: " + DoubleToStr(sl, _Digits)  
                   + ", \nTP: " + DoubleToStr(tp, _Digits);
              Print(info);
              Comment(info);
          
                retVal = OrderSend(symbolName, pendingType, volume, entryPrice, Slippage, sl, tp, comment, MagicNumber, 0, MediumVioletRed);
                if (retVal < 0)  
                {
                    retVal = OrderSend(symbolName, pendingType, volume, entryPrice, Slippage, 0, 0, comment, MagicNumber, 0, Red);
                    modifyOrderByPrice(retVal, entryPrice, sl, tp);          
                }
                break;
      }
           
      if( retVal > 0 ) { return( retVal ); }
      else {
         Print("DoPending pendingType:", pendingType, " error: \'"+ErrorDescription(GetLastError())+"\' when setting entry order");
         Sleep(RETRYDELAY);      
      }
      
   }
      
   return( retVal );
}


//return error message for each kind of errorCode
string ErrorDescription(int error_code)
{
    string error_string;

    switch( error_code ) {
        case 0:
        case 1:   error_string="no error";                                                  break;
        case 2:   error_string="common error";                                              break;
        case 3:   error_string="invalid trade parameters";                                  break;
        case 4:   error_string="trade server is busy";                                      break;
        case 5:   error_string="old version of the client terminal";                        break;
        case 6:   error_string="no connection with trade server";                           break;
        case 7:   error_string="not enough rights";                                         break;
        case 8:   error_string="too frequent requests";                                     break;
        case 9:   error_string="malfunctional trade operation (never returned error)";      break;
        case 64:  error_string="account disabled";                                          break;
        case 65:  error_string="invalid account";                                           break;
        case 128: error_string="trade timeout";                                             break;
        case 129: error_string="invalid price";                                             break;
        case 130: error_string="invalid stops";                                             break;
        case 131: error_string="invalid trade volume";                                      break;
        case 132: error_string="market is closed";                                          break;
        case 133: error_string="trade is disabled";                                         break;
        case 134: error_string="not enough money";                                          break;
        case 135: error_string="price changed";                                             break;
        case 136: error_string="off quotes";                                                break;
        case 137: error_string="broker is busy (never returned error)";                     break;
        case 138: error_string="requote";                                                   break;
        case 139: error_string="order is locked";                                           break;
        case 140: error_string="long positions only allowed";                               break;
        case 141: error_string="too many requests";                                         break;
        case 145: error_string="modification denied because order too close to market";     break;
        case 146: error_string="trade context is busy";                                     break;
        case 147: error_string="expirations are denied by broker";                          break;
        case 148: error_string="amount of open and pending orders has reached the limit";   break;
        case 149: error_string="hedging is prohibited";                                     break;
        case 150: error_string="prohibited by FIFO rules";                                  break;
        case 4000: error_string="no error (never generated code)";                          break;
        case 4001: error_string="wrong function pointer";                                   break;
        case 4002: error_string="array index is out of range";                              break;
        case 4003: error_string="no memory for function call stack";                        break;
        case 4004: error_string="recursive stack overflow";                                 break;
        case 4005: error_string="not enough stack for parameter";                           break;
        case 4006: error_string="no memory for parameter string";                           break;
        case 4007: error_string="no memory for temp string";                                break;
        case 4008: error_string="not initialized string";                                   break;
        case 4009: error_string="not initialized string in array";                          break;
        case 4010: error_string="no memory for array\' string";                             break;
        case 4011: error_string="too long string";                                          break;
        case 4012: error_string="remainder from zero divide";                               break;
        case 4013: error_string="zero divide";                                              break;
        case 4014: error_string="unknown command";                                          break;
        case 4015: error_string="wrong jump (never generated error)";                       break;
        case 4016: error_string="not initialized array";                                    break;
        case 4017: error_string="dll calls are not allowed";                                break;
        case 4018: error_string="cannot load library";                                      break;
        case 4019: error_string="cannot call function";                                     break;
        case 4020: error_string="expert function calls are not allowed";                    break;
        case 4021: error_string="not enough memory for temp string returned from function"; break;
        case 4022: error_string="system is busy (never generated error)";                   break;
        case 4050: error_string="invalid function parameters count";                        break;
        case 4051: error_string="invalid function parameter value";                         break;
        case 4052: error_string="string function internal error";                           break;
        case 4053: error_string="some array error";                                         break;
        case 4054: error_string="incorrect series array using";                             break;
        case 4055: error_string="custom indicator error";                                   break;
        case 4056: error_string="arrays are incompatible";                                  break;
        case 4057: error_string="global variables processing error";                        break;
        case 4058: error_string="global variable not found";                                break;
        case 4059: error_string="function is not allowed in testing mode";                  break;
        case 4060: error_string="function is not confirmed";                                break;
        case 4061: error_string="send mail error";                                          break;
        case 4062: error_string="string parameter expected";                                break;
        case 4063: error_string="integer parameter expected";                               break;
        case 4064: error_string="double parameter expected";                                break;
        case 4065: error_string="array as parameter expected";                              break;
        case 4066: error_string="requested history data in update state";                   break;
        case 4099: error_string="end of file";                                              break;
        case 4100: error_string="some file error";                                          break;
        case 4101: error_string="wrong file name";                                          break;
        case 4102: error_string="too many opened files";                                    break;
        case 4103: error_string="cannot open file";                                         break;
        case 4104: error_string="incompatible access to a file";                            break;
        case 4105: error_string="no order selected";                                        break;
        case 4106: error_string="unknown symbol";                                           break;
        case 4107: error_string="invalid price parameter for trade function";               break;
        case 4108: error_string="invalid ticket";                                           break;
        case 4109: error_string="trade is not allowed in the expert properties";            break;
        case 4110: error_string="longs are not allowed in the expert properties";           break;
        case 4111: error_string="shorts are not allowed in the expert properties";          break;
        case 4200: error_string="object is already exist";                                  break;
        case 4201: error_string="unknown object property";                                  break;
        case 4202: error_string="object is not exist";                                      break;
        case 4203: error_string="unknown object type";                                      break;
        case 4204: error_string="no object name";                                           break;
        case 4205: error_string="object coordinates error";                                 break;
        case 4206: error_string="no specified subwindow";                                   break;
        default:   error_string="unknown error";
    }

    return(error_string);
}